]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
keyboard: Delete selected text on backspace
authorSebastian Keller <skeller@gnome.org>
Fri, 21 Apr 2023 22:05:22 +0000 (00:05 +0200)
committerCarlos Garnacho <carlosg@gnome.org>
Thu, 29 Feb 2024 14:56:16 +0000 (14:56 +0000)
Previously backspace would only ever remove a single character left of
the cursor, regardless of selection.

This requires the application to correctly set the anchor position in
text_input::set_surrounding_text(), which currently only gtk4 seems to
do. When there is no selection or on other applications that always set
cursor = anchor, like gtk3 does, the behavior is not changed and still
only deletes one character.

Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/2746>

js/misc/inputMethod.js
js/ui/keyboard.js

index d169ea8cbe1f91fc9107f3e7e951193463bac550..53af39d8582230a1e33a4798ce7334b6b38c57d6 100644 (file)
@@ -227,6 +227,7 @@ export const InputMethod = GObject.registerClass({
 
         this._surroundingText = null;
         this._surroundingTextCursor = null;
+        this._surroundingTextAnchor = null;
         this._preeditStr = null;
         this._setTerminalMode(false);
     }
@@ -247,6 +248,7 @@ export const InputMethod = GObject.registerClass({
     vfunc_set_surrounding(text, cursor, anchor) {
         this._surroundingText = text;
         this._surroundingTextCursor = cursor;
+        this._surroundingTextAnchor = anchor;
         this.emit('surrounding-text-set');
 
         if (!this._context || (!text && text !== ''))
@@ -348,7 +350,11 @@ export const InputMethod = GObject.registerClass({
     }
 
     getSurroundingText() {
-        return [this._surroundingText, this._surroundingTextCursor];
+        return [
+            this._surroundingText,
+            this._surroundingTextCursor,
+            this._surroundingTextAnchor,
+        ];
     }
 
     hasPreedit() {
index 180bc6b29417b07985a0e53ce5ab66e966b3d666..38f1b8ee3a3dcdfc412cc50fdc13a5b6625d7640 100644 (file)
@@ -1650,24 +1650,35 @@ export const Keyboard = GObject.registerClass({
         }
 
         if (enabled) {
-            let func = (text, cursor) => {
-                if (cursor === 0)
+            let func = (text, cursor, anchor) => {
+                if (cursor === 0 && anchor === 0)
                     return;
 
-                const anchor = this._timesDeleted < BACKSPACE_WORD_DELETE_THRESHOLD
-                    ? cursor - 1
-                    : this._previousWordPosition(text, cursor);
-                const offset = anchor - cursor;
+                let offset, len;
+                if (cursor > anchor) {
+                    offset = anchor - cursor;
+                    len = -offset;
+                } else if (cursor < anchor) {
+                    offset = 0;
+                    len = anchor - cursor;
+                } else if (this._timesDeleted < BACKSPACE_WORD_DELETE_THRESHOLD) {
+                    offset = -1;
+                    len = 1;
+                } else {
+                    const wordLength = cursor - this._previousWordPosition(text, cursor);
+                    offset = -wordLength;
+                    len = wordLength;
+                }
 
                 this._timesDeleted++;
-                Main.inputMethod.delete_surrounding(offset, Math.abs(offset));
+                Main.inputMethod.delete_surrounding(offset, len);
             };
 
             this._surroundingUpdateId = Main.inputMethod.connect(
                 'surrounding-text-set', () => {
-                    let [text, cursor] = Main.inputMethod.getSurroundingText();
+                    let [text, cursor, anchor] = Main.inputMethod.getSurroundingText();
                     if (this._timesDeleted === 0) {
-                        func(text, cursor);
+                        func(text, cursor, anchor);
                     } else {
                         if (this._surroundingUpdateTimeoutId > 0) {
                             GLib.source_remove(this._surroundingUpdateTimeoutId);
@@ -1675,16 +1686,16 @@ export const Keyboard = GObject.registerClass({
                         }
                         this._surroundingUpdateTimeoutId =
                             GLib.timeout_add(GLib.PRIORITY_DEFAULT, KEY_RELEASE_TIMEOUT, () => {
-                                func(text, cursor);
+                                func(text, cursor, cursor);
                                 this._surroundingUpdateTimeoutId = 0;
                                 return GLib.SOURCE_REMOVE;
                             });
                     }
                 });
 
-            let [text, cursor] = Main.inputMethod.getSurroundingText();
+            let [text, cursor, anchor] = Main.inputMethod.getSurroundingText();
             if (text)
-                func(text, cursor);
+                func(text, cursor, anchor);
             else
                 Main.inputMethod.request_surrounding();
         } else {